use std::sync::Arc;
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use ringbuf::{HeapRb, Consumer};
use super::{resampler::HighQualityResampler, preprocessor::AudioPreprocessor, quality::AudioQualityConfig};

pub struct AudioRecorder {
    pub(crate) _stream: cpal::Stream,
    pub(crate) consumer: Consumer<f32, Arc<HeapRb<f32>>>,
    pub(crate) input_sample_rate: u32,
    pub(crate) target_sample_rate: u32,
    pub(crate) target_channels: u32,
    pub(crate) resampler: Option<HighQualityResampler>,
    pub(crate) preprocessor: AudioPreprocessor,
}

impl AudioRecorder {
    pub fn new(target_sample_rate: u32, target_channels: u32) -> Result<Self, Box<dyn std::error::Error>> {
        let host = cpal::default_host();
        let device = host.default_input_device().ok_or("没有找到默认音频输入设备")?;
        let config = device.default_input_config().map_err(|e| format!("无法获取默认音频输入配置: {}", e))?;
        log::info!("音频输入设备: {}, 配置: {:?}", device.name()?, config);
        let input_sample_rate = config.sample_rate().0;
        let buffer_size = (input_sample_rate as f32 * 1.0) as usize;
        let ring_buffer = HeapRb::<f32>::new(buffer_size);
        let (mut producer, consumer) = ring_buffer.split();
        let stream = device.build_input_stream(
            &config.into(),
            move |data: &[f32], _| { for &sample in data { if producer.push(sample).is_err() { break; } } },
            |err| log::error!("麦克风录音错误: {}", err),
            None,
        )?;
        stream.play()?;
        let resampler = if input_sample_rate != target_sample_rate { Some(HighQualityResampler::new(input_sample_rate, target_sample_rate, 1)?) } else { None };
        let audio_config = AudioQualityConfig::default();
        let preprocessor = AudioPreprocessor::new(audio_config);
        Ok(Self { _stream: stream, consumer, input_sample_rate, target_sample_rate, target_channels, resampler, preprocessor })
    }

    pub fn read_audio(&mut self) -> Result<Vec<i16>, Box<dyn std::error::Error>> {
        let mut samples = Vec::new();
        while let Some(sample) = self.consumer.pop() { samples.push(sample); }
        if samples.is_empty() { return Ok(Vec::new()); }
        let mono_samples = self.convert_to_mono(&samples);
        let mut processed_samples = mono_samples;
        self.preprocessor.process(&mut processed_samples);
        let resampled = if let Some(ref mut resampler) = self.resampler { resampler.process(&processed_samples)? } else { processed_samples };
        let output: Vec<i16> = resampled.iter().map(|&s| { let clamped = s.max(-1.0).min(1.0); (clamped * 32767.0) as i16 }).collect();
        Ok(output)
    }

    fn convert_to_mono(&self, input_samples: &[f32]) -> Vec<f32> {
        let input_channels = 2;
        if input_samples.len() % input_channels != 0 { return input_samples.to_vec(); }
        let frames = input_samples.len() / input_channels;
        let mut mono_samples = Vec::with_capacity(frames);
        for frame in 0..frames { let left = input_samples[frame * input_channels]; let right = input_samples[frame * input_channels + 1]; mono_samples.push((left + right) * 0.5); }
        mono_samples
    }
}


